<?php
declare(strict_types=1);

namespace App\Logic\User\Service;

use App\Constant\CacheKey;
use App\Exceptions\ScoreException;
use App\Library\RedisClient;
use App\Library\SnowFlakeId;
use App\Logic\User\Repository\UserScoreHistoryRepository;
use Closure;

class UserScoreHistoryService extends BaseService implements UserServiceInterface
{
    public static function searchWhere(array $requestParams): Closure
    {
        return function ($query) use ($requestParams) {
            extract($requestParams);
            $query->where("user_uid", "=", $requestParams["user_uid"]);
        };
    }

    public function serviceSelect(array $requestParams): array
    {
        $requestParams["user_uid"] = $this->getUserUid();
        return (new UserScoreHistoryRepository())->repositorySelect(
            self::searchWhere($requestParams),
            (int)($requestParams["size"] ?? 20),
            ["title", "created_at as in_time", "score", "type"]
        );
    }

    public function serviceAdd(array $requestParams): array
    {
        return $this->serviceCreate([
            "type" => 1,
            "title" => $requestParams["title"],
            "score" => 20,
        ]);
    }

    public function serviceCreate(array $requestParams): array
    {
        $userUid = $this->getUserUid();
        if ($requestParams["type"] == 2) {
            $userScore = RedisClient::client()->get(CacheKey::$scoreKey . $userUid);
            if ($userScore < $requestParams["score"]) {
                throw new ScoreException("积分不足");
            }
        }
        $id = SnowFlakeId::getId();
        $createResult = (new UserScoreHistoryRepository())->repositoryCreate([
            "uid" => $id,
            "user_uid" => $userUid,
            "score" => $requestParams["score"],
            "title" => $requestParams["title"],
            "type" => $requestParams["type"],
        ]);
        if ($requestParams["type"] == 1) {
            $updateScore = RedisClient::client()->incrByFloat(CacheKey::$scoreKey . $userUid, (float)$requestParams["score"]);
        } else {
            $updateScore = RedisClient::client()->incrByFloat(CacheKey::$scoreKey . $userUid, -(float)$requestParams["score"]);
        }
        if ($createResult && $updateScore) {
            return ["uid" => $id, "code" => 1, "user_uid" => $userUid, "score" => $requestParams["score"]];
        }
        return ["uid" => 0, "code" => 2,];
    }

    public function serviceUpdate(array $requestParams): array
    {
        return [];
    }

    public function serviceDelete(array $requestParams): int
    {
        return 0;
    }

    public function serviceFind(array $requestParams): array
    {
        return [];
    }
}
